﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mvp.DTO;

namespace Mvp.Task
{
    /*
     * DataAccess 项目中的IBookMapper.GetAllBook()方法返回的是IList<BookDTO>,而这里需要的是一个ILookupCollection
     * 回头看一下ILookupCollection的实现,它内部维护的是一个IList<ILookupDTO>,ILookupDTO是业务无关的,
     * 它包含了Text和Value属性用于向页面上的DropDownList的列表项提供数据。
     * 在本例中,ILookupDTO的Text应该为书名,而Value应该为书的Id。
     * 这样,最好能创建一个Converter类,能够进行由BookDTO到ILookupDTO的转换,进而由IList<BookDTO>到IList<ILookupDTO>的转换。
     * 最后将转换好的IList<ILookupDTO>作为参数传递给ILookupCollection的构造函数,从而得到一个ILookupCollection。
     * 注意到ILookupDTO是业务无关的,所以我们定义接口名称,为ObjectToLookupConverter,而非BookToLookupConverter。
     * 另外,注意以后我们有可能创建其他的类型,比如Customer(客户)也能转换为LookupDTO,
     * 所以我们定义一个泛型接口(使得Converter类不限于BookDTO才能使用)
     */

    public interface IObjectToLookupConverter<T>
    {
        /// <summary>
        /// 将T类型的对象转换为ILoopupDTO类型
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        ILoopupDTO ConvertFrom(T obj);

        IList<ILoopupDTO> ConvertAllFrom(IList<T> obj);
    }

    public abstract class ObjectToLookupConverter<T> : IObjectToLookupConverter<T>
    {
        #region IObjectToLookupConverter<T> 成员

        /// <summary>
        /// 具体类实现的时候可自行决定其什么属性做为Value及Text
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public abstract ILoopupDTO ConvertFrom(T obj);

        public IList<ILoopupDTO> ConvertAllFrom(IList<T> obj)
        {
            List<T> list = new List<T>(obj);

            return list.ConvertAll(x => ConvertFrom(x));
        }

        #endregion
    }

    public sealed class BookToLookupConverter : ObjectToLookupConverter<BookDTO>
    {
        public override ILoopupDTO ConvertFrom(BookDTO obj)
        {
            return new SimpleLoopupDTO(obj.ID.ToString(), obj.Title);
        }
    }
}
